package com.ccteam.admin.view.fragments.album

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.ccteam.admin.REFRESH_REQUEST_KEY
import com.ccteam.admin.databinding.AlbumMusicItemBinding
import com.ccteam.admin.databinding.FragmentAlbumMusicHomeBinding
import com.ccteam.admin.utils.LoadMessage
import com.ccteam.admin.viewmodels.album.AlbumMusicHomeViewModel
import com.ccteam.model.album.AlbumVO
import com.ccteam.model.music.MusicDetailVO
import com.ccteam.model.music.MusicVO
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch

@AndroidEntryPoint
class AlbumMusicHomeFragment : Fragment() {

    private var _binding: FragmentAlbumMusicHomeBinding? = null
    private val binding get() = _binding!!

    private val albumMusicHomeViewModel by viewModels<AlbumMusicHomeViewModel>()

    private val args by navArgs<AlbumMusicHomeFragmentArgs>()

    private lateinit var adapter: AlbumMusicRVAdapter

    companion object{
        val differCallback = object: DiffUtil.ItemCallback<MusicDetailVO>(){

            override fun areItemsTheSame(oldItem: MusicDetailVO, newItem: MusicDetailVO): Boolean {
                return oldItem == newItem
            }

            override fun areContentsTheSame(oldItem: MusicDetailVO, newItem: MusicDetailVO): Boolean {
                return oldItem == newItem
            }

        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentAlbumMusicHomeBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        adapter = AlbumMusicRVAdapter(callback)
        binding.rvAlbumMusicList.adapter = adapter

        setFragmentResultListener(REFRESH_REQUEST_KEY) { _, bundle ->
            bundle.getBoolean(REFRESH_REQUEST_KEY).let {
                viewLifecycleOwner.lifecycleScope.launch {
                    albumMusicHomeViewModel.refreshAlbumMusic()
                }
            }
        }

        binding.btnAdd.setOnClickListener {
            findNavController().navigate(AlbumMusicHomeFragmentDirections
                    .actionAlbumMusicHomeFragmentToMusicAddFragment(args.albumId,args.albumName)
            )
        }

        albumMusicHomeViewModel.loadMessage.observe(viewLifecycleOwner, {
            binding.refreshView.isRefreshing = it is LoadMessage.Loading
            binding.statusView.changeToLoadingStatus(it is LoadMessage.Loading)
            binding.statusView.changeToErrorStatus(it)
        })

        albumMusicHomeViewModel.albumMusicList.observe(viewLifecycleOwner, {
            adapter.submitList(it)
        })

        binding.refreshView.setOnRefreshListener {
            albumMusicHomeViewModel.refreshAlbumMusic()
        }

        binding.statusView.setRetryClickListener {
            albumMusicHomeViewModel.refreshAlbumMusic()
        }
    }

    private val callback = object: AlbumMusicItemCallback{
        override fun editMusicInfoClicked(item: MusicDetailVO) {
            findNavController().navigate(AlbumMusicHomeFragmentDirections
                .actionAlbumMusicHomeFragmentToMusicEditFragment(
                    item.id))
        }

    }

    class AlbumMusicRVAdapter(
        private val callback: AlbumMusicItemCallback
    ): ListAdapter<MusicDetailVO, AlbumMusicRVAdapter.AlbumMusicItemViewHolder>(differCallback){

        inner class AlbumMusicItemViewHolder(
            private val callback: AlbumMusicItemCallback,
            val binding: AlbumMusicItemBinding
        ): RecyclerView.ViewHolder(binding.root){
            var item: MusicDetailVO? = null

            init {
                binding.btnEditMusicInfo.setOnClickListener {
                    item?.let {
                        callback.editMusicInfoClicked(it)
                    }
                }

                binding.root.setOnClickListener {
                    item?.let {
                        callback.editMusicInfoClicked(it)
                    }
                }
            }
        }

        override fun onCreateViewHolder(
            parent: ViewGroup,
            viewType: Int
        ): AlbumMusicItemViewHolder {
            return AlbumMusicItemViewHolder(
                callback,
                AlbumMusicItemBinding.inflate(LayoutInflater.from(parent.context),parent,false)
            )
        }

        override fun onBindViewHolder(holder: AlbumMusicItemViewHolder, position: Int) {
            getItem(position)?.let { item ->
                holder.item = item
                holder.binding.tvMusicName.text = item.name
                Glide.with(holder.binding.ivMusic)
                    .load(item.imgUrl)
                    .into(holder.binding.ivMusic)
            }

        }
    }

    interface AlbumMusicItemCallback{
        fun editMusicInfoClicked(item: MusicDetailVO)
    }

    override fun onDestroyView() {
        super.onDestroyView()

        _binding = null
    }
}